package cn.king.springframework.beans.factory.annotation;

import cn.hutool.core.bean.BeanUtil;
import cn.king.springframework.beans.BeanException;
import cn.king.springframework.beans.PropertyValues;
import cn.king.springframework.beans.factory.BeanFactory;
import cn.king.springframework.beans.factory.BeanFactoryAware;
import cn.king.springframework.beans.factory.ConfigurableListableBeanFactory;
import cn.king.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import cn.king.springframework.util.ClassUtil;

import java.lang.reflect.Field;

public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
    private ConfigurableListableBeanFactory beanFactory;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeanException {
        this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeanException {
        //1、处理注解@Value
        Class<?> clazz = bean.getClass();
        clazz = ClassUtil.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field field:declaredFields){
            Value valueAnnotation = field.getAnnotation(Value.class);
            if(null != valueAnnotation){
                String value = valueAnnotation.value();
                value = beanFactory.resolveEmbeddedValue(value);
                BeanUtil.setFieldValue(bean,field.getName(),value);
            }
        }
        //2、处理Autowire注解--注入属性
        for(Field field:declaredFields){
            Autowired autowireAnnotation = field.getAnnotation(Autowired.class);
            if(null != autowireAnnotation){
                Class<?> fieldType = field.getType();
                String qualiferName = null;
                Object dependentBean = null;
                Qualifer qualiferAnnotation = field.getAnnotation(Qualifer.class);
                if(null != qualiferAnnotation){
                    qualiferName = qualiferAnnotation.value();
                    dependentBean = beanFactory.getBean(qualiferName,fieldType);
                }else{
                    dependentBean = beanFactory.getBean(fieldType);
                }
                BeanUtil.setFieldValue(bean,qualiferName,dependentBean);
            }
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialzation(Object bean, String beanName) throws BeanException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialzation(Object bean, String beanName) throws BeanException {
        return null;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeanException {
        return null;
    }
}
